home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 April: Mac OS SDK / Dev.CD Apr 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / Skinny3DSample / Skinny3DSources ƒ / Lights.c < prev    next >
Encoding:
Text File  |  1996-05-21  |  12.1 KB  |  361 lines  |  [TEXT/MPS ]

  1. // file Lights.c
  2.  
  3. #include "SkinnyMain.h"
  4. #include "Lights.h"
  5. // #include "ValueControls.h"
  6.  
  7. // local prototypes
  8. static VccPtr     LightDataToVcc        (TQ3LightData               lightData);
  9. static VccPtr     DirectLightDataToVcc(TQ3DirectionalLightData drLightData);
  10. static VccPtr     PointLightDataToVcc    (TQ3PointLightData         ptLightData);
  11. static VccPtr     SpotLightDataToVcc    (TQ3SpotLightData         spLightData);
  12. static void     AddStdLightDataValues(VccPtr vcc, TQ3LightData lightData);
  13.  
  14. static void    VccToLightData        (VccPtr vcc, TQ3LightData               *lightData);
  15. static void    VccToDirectLightData(VccPtr vcc, TQ3DirectionalLightData *drLightData);
  16. static void    VccToPointLightData    (VccPtr vcc, TQ3PointLightData         *ptLightData);
  17. static void    VccToSpotLightData    (VccPtr vcc, TQ3SpotLightData         *spLightData);
  18. static void GetStdLightDataValues(VccPtr vcc, TQ3LightData             *lightData);
  19.  
  20. static TQ3LightObject FindLight(TQ3GroupObject lightGroup, TQ3ObjectType lType);
  21.  
  22. extern Rect gContrlRect;
  23.  
  24.  
  25. // --------------------------------------------------------------------
  26. TQ3GroupObject MakeLights(void)
  27. {
  28.     TQ3GroupPosition            groupPosition;
  29.     TQ3GroupObject            lightGroup;
  30.     TQ3LightData                lightData;
  31.     TQ3PointLightData        pointLightData;
  32.     TQ3DirectionalLightData    directLightData;
  33.     TQ3SpotLightData            spotLightData;
  34.     TQ3LightObject            ambientLight, pointLight, fillLight, spotLight;
  35.     TQ3Point3D                pointLocation = { -10.0, 0.0, 10.0 };
  36.     TQ3Vector3D                fillDirection = { -5.0, 0.0, 10.0 };
  37.     TQ3Point3D                spotLocation = { -10.0, 10.0, 10.0 };
  38.     TQ3Vector3D                spotDirection = { 10.0, -10.0, -10.0 };
  39.     TQ3ColorRGB                WhiteLight = { 1.0, 1.0, 1.0 };
  40.     
  41.     //    Set up light data for ambient light.  This light data will be used for point and fill
  42.     //    light also.
  43.  
  44.     lightData.isOn          = kQ3True;
  45.     lightData.color      = WhiteLight;
  46.     lightData.brightness = .2;
  47.     
  48.     //    Create ambient light.
  49.     ambientLight = Q3AmbientLight_New(&lightData);
  50.     if ( ambientLight == nil ) goto bail;
  51.     
  52.     //    Create point light.
  53.     lightData.brightness = 1.0;
  54.     pointLightData.lightData         = lightData;
  55.     pointLightData.castsShadows     = kQ3False;
  56.     pointLightData.attenuation         = kQ3AttenuationTypeNone;
  57.     pointLightData.location         = pointLocation;
  58.     pointLight = Q3PointLight_New(&pointLightData);
  59.     if ( pointLight == nil ) goto bail;
  60.  
  61.     //    Create fill light.
  62.     lightData.brightness = .8;
  63.     directLightData.lightData         = lightData;
  64.     directLightData.castsShadows     = kQ3False;
  65.     directLightData.direction         = fillDirection;
  66.     fillLight = Q3DirectionalLight_New(&directLightData);
  67.     if ( fillLight == nil ) goto bail;
  68.  
  69.     //    Create spot light.
  70.     lightData.brightness = .4;
  71.     spotLightData.lightData     = lightData;
  72.     spotLightData.castsShadows     = kQ3False;
  73.     spotLightData.attenuation     = kQ3AttenuationTypeNone;
  74.     spotLightData.location         = spotLocation;
  75.     spotLightData.direction     = spotDirection;
  76.     spotLightData.hotAngle         = 0.2;
  77.     spotLightData.outerAngle     = 0.4;
  78.     spotLightData.fallOff         = kQ3FallOffTypeLinear;
  79.     
  80.     spotLight = Q3SpotLight_New(&spotLightData);
  81.     if ( spotLight == nil ) goto bail;
  82.  
  83.     //    Create light group and add each of the lights into the group.
  84.     lightGroup = Q3LightGroup_New();
  85.     if ( lightGroup == nil ) goto bail;
  86.     
  87.     groupPosition = Q3Group_AddObject(lightGroup, ambientLight);
  88.     if ( groupPosition == 0 ) goto bail;
  89.     groupPosition = Q3Group_AddObject(lightGroup, pointLight);
  90.     if ( groupPosition == 0 ) goto bail;
  91.     groupPosition = Q3Group_AddObject(lightGroup, fillLight);
  92.     if ( groupPosition == 0 ) goto bail;
  93.     groupPosition = Q3Group_AddObject(lightGroup, spotLight);
  94.     if ( groupPosition == 0 ) goto bail;
  95.  
  96.     //    Done!
  97.     return ( lightGroup );
  98.     
  99. bail: // If any of the above failed, then return nothing!
  100.     return ( nil );
  101. }
  102.  
  103.  
  104. // --------------------------------------------------------------------
  105. static TQ3LightObject FindLight(TQ3GroupObject lightGroup, TQ3ObjectType lType)
  106. {
  107.     TQ3Status        status;
  108.     TQ3Object        object;
  109.     TQ3LightObject     light;
  110.     TQ3GroupPosition    position;
  111.     Boolean            found = false;
  112.  
  113.     status = Q3Group_GetFirstPosition(lightGroup, &position);
  114.     if (status != kQ3Success)
  115.         return NULL;
  116.     do {
  117.         status = Q3Group_GetPositionObject(lightGroup, position, &object);
  118.         if (object == NULL)
  119.             return NULL;
  120.         light = (TQ3LightObject)object;
  121.         found = (Q3Light_GetType(light) == lType);
  122.         status = Q3Group_GetNextPosition(lightGroup, &position);
  123.     } while ((!found) && (position != NULL));
  124.     if (found)
  125.         return light;
  126.     else
  127.         return NULL;
  128. }
  129.  
  130.  
  131. // --------------------------------------------------------------------
  132. VccPtr     LightToVCC(TQ3GroupObject lightGroup, long selector)
  133. {
  134.     TQ3LightObject     light;
  135.     TQ3Status        status;
  136.     TQ3ObjectType    lType;
  137.     TQ3LightData                lightData;
  138.     TQ3DirectionalLightData    drLightData;
  139.     TQ3PointLightData        ptLightData;
  140.     TQ3SpotLightData            spLightData;
  141.     
  142.     switch (selector) {
  143.         case iAmbient:         lType = kQ3LightTypeAmbient;        break;
  144.         case iDirectional:     lType = kQ3LightTypeDirectional;    break;
  145.         case iPoint:         lType = kQ3LightTypePoint;            break;
  146.         case iSpot:         lType = kQ3LightTypeSpot;            break;
  147.         default:    return nil;
  148.     }
  149.     light = FindLight(lightGroup, lType);
  150.     
  151.     switch (selector) {
  152.         case iAmbient:
  153.                 status = Q3AmbientLight_GetData(light, &lightData);
  154.                 return LightDataToVcc(lightData);
  155.             break;
  156.         case iDirectional:
  157.                 status = Q3DirectionalLight_GetData(light, &drLightData);
  158.                 return DirectLightDataToVcc(drLightData);
  159.             break;
  160.         case iPoint:
  161.                 status = Q3PointLight_GetData(light, &ptLightData);
  162.                 return PointLightDataToVcc(ptLightData);
  163.             break;
  164.         case iSpot:
  165.                 status = Q3SpotLight_GetData(light, &spLightData);
  166.                 return SpotLightDataToVcc(spLightData);
  167.             break;
  168.         default:
  169.             return nil;
  170.     }
  171. }
  172.  
  173.  
  174. #define cBasicLines 7
  175.  
  176. // --------------------------------------------------------------------
  177. static VccPtr     LightDataToVcc(TQ3LightData lightData)
  178. {
  179.     VccPtr         vcc;
  180.  
  181.     vcc = NewVCluster((long)kQ3LightTypeAmbient, "\pAmbientLightData", cBasicLines, &gContrlRect);
  182.     if (vcc == nil) return nil;
  183.     AddStdLightDataValues(vcc, lightData);
  184.     return vcc;
  185. }
  186.  
  187.  
  188. // --------------------------------------------------------------------
  189. static VccPtr     DirectLightDataToVcc(TQ3DirectionalLightData drLightData)
  190. {
  191.     VccPtr         vcc;
  192.  
  193.     vcc = NewVCluster((long)kQ3LightTypeDirectional, "\pDirectionalLightData", 
  194.                                                                 cBasicLines + 4, &gContrlRect);
  195.     if (vcc == nil) return nil;
  196.     AddStdLightDataValues(vcc, drLightData.lightData);
  197.     AddValueCtl(vcc, "\pcastsShadows", drLightData.castsShadows,   0.0, 1.0, 1.0); // [7]
  198.     AddValueCtl(vcc, "\pdirection.x",  drLightData.direction.x,  -30.0, 30.0, 3.0);
  199.     AddValueCtl(vcc, "\pdirection.y",  drLightData.direction.y,  -30.0, 30.0, 3.0);
  200.     AddValueCtl(vcc, "\pdirection.z",  drLightData.direction.z,  -30.0, 30.0, 3.0);
  201.     return vcc;
  202. }
  203.  
  204.  
  205. // --------------------------------------------------------------------
  206. static VccPtr     PointLightDataToVcc(TQ3PointLightData ptLightData)
  207. {
  208.     VccPtr         vcc;
  209.  
  210.     vcc = NewVCluster((long)kQ3LightTypePoint, "\pPointLightData", cBasicLines + 6, &gContrlRect);
  211.     if (vcc == nil) return nil;
  212.     AddStdLightDataValues(vcc, ptLightData.lightData);
  213.     AddValueCtl(vcc, "\pcastsShadows", ptLightData.castsShadows, 0.0, 1.0, 1.0); // [7]
  214.     AddValueCtl(vcc, "\pattenuation", ptLightData.attenuation,     0.0,  2.0, 1.0);
  215.     AddSeparator(vcc);
  216.     AddValueCtl(vcc, "\plocation.x", ptLightData.location.x,  -30.0, 30.0, 3.0); // [10]
  217.     AddValueCtl(vcc, "\plocation.y", ptLightData.location.y,  -30.0, 30.0, 3.0);
  218.     AddValueCtl(vcc, "\plocation.z", ptLightData.location.z,  -30.0, 30.0, 3.0);
  219.     return vcc;
  220. }
  221.  
  222.  
  223. // --------------------------------------------------------------------
  224. static VccPtr     SpotLightDataToVcc(TQ3SpotLightData spLightData)
  225. {
  226.     VccPtr         vcc;
  227.  
  228.     vcc = NewVCluster((long)kQ3LightTypeSpot, "\pSpotLightData", cBasicLines + 14, &gContrlRect);
  229.     if (vcc == nil) return nil;
  230.     AddStdLightDataValues(vcc, spLightData.lightData);
  231.     AddValueCtl(vcc, "\pcastsShadows", spLightData.castsShadows, 0.0, 1.0, 1.0); // [7]
  232.     AddValueCtl(vcc, "\pattenuation", spLightData.attenuation,     0.0,  2.0, 1.0);
  233.     AddSeparator(vcc);
  234.     AddValueCtl(vcc, "\plocation.x", spLightData.location.x,  -30.0, 30.0, 3.0); // [10]
  235.     AddValueCtl(vcc, "\plocation.y", spLightData.location.y,  -30.0, 30.0, 3.0);
  236.     AddValueCtl(vcc, "\plocation.z", spLightData.location.z,  -30.0, 30.0, 3.0);
  237.     AddSeparator(vcc);
  238.     AddValueCtl(vcc, "\pdirection.x", spLightData.direction.x,  -30.0, 30.0, 3.0); // [14]
  239.     AddValueCtl(vcc, "\pdirection.y", spLightData.direction.y,  -30.0, 30.0, 3.0);
  240.     AddValueCtl(vcc, "\pdirection.z", spLightData.direction.z,  -30.0, 30.0, 3.0);
  241.     AddSeparator(vcc);
  242.     AddValueCtl(vcc, "\photAngle",   spLightData.hotAngle,     0.05, 1.0, 0.05);  // [18]
  243.     AddValueCtl(vcc, "\pouterAngle", spLightData.outerAngle, 0.1, 2.0, 0.1);
  244.     AddValueCtl(vcc, "\pfallOff",      spLightData.fallOff,     0.0, 3.0, 1.0);
  245.     return vcc;
  246. }
  247.  
  248.  
  249. // --------------------------------------------------------------------
  250. static void AddStdLightDataValues(VccPtr vcc, TQ3LightData lightData)
  251. {
  252.     AddValueCtl(vcc, "\pisOn",         lightData.isOn,          0.0, 1.0, 1.0); // [0]
  253.     AddValueCtl(vcc, "\pbrightness",lightData.brightness, 0.0, 1.0, 0.1);
  254.     AddSeparator(vcc);
  255.     AddValueCtl(vcc, "\pcolor.r",     lightData.color.r,      0.0, 1.0, 0.1); // [3]
  256.     AddValueCtl(vcc, "\pcolor.g",     lightData.color.g,       0.0, 1.0, 0.1);
  257.     AddValueCtl(vcc, "\pcolor.b",     lightData.color.b,       0.0, 1.0, 0.1);
  258.     AddSeparator(vcc); // cBasicLines = 7
  259. }
  260.  
  261.  
  262. // --------------------------------------------------------------------
  263. void VCCtoLight(VccPtr vcc, TQ3GroupObject lightGroup)
  264. {
  265.     TQ3LightData                lightData;
  266.     TQ3DirectionalLightData    drLightData;
  267.     TQ3PointLightData        ptLightData;
  268.     TQ3SpotLightData            spLightData;
  269.     TQ3Status                status;
  270.     TQ3LightObject             light;
  271.     TQ3ObjectType            lType;
  272.     
  273.     lType = (TQ3ObjectType)GetIdTag(vcc);
  274.     light = FindLight(lightGroup, lType);
  275.     if (light == NULL)
  276.         return;
  277.         
  278.     switch    (lType) {
  279.         case kQ3LightTypeAmbient:
  280.                 VccToLightData(vcc, &lightData);
  281.                 status = Q3AmbientLight_SetData(light, &lightData);
  282.             break;
  283.         case kQ3LightTypeDirectional:
  284.                 VccToDirectLightData(vcc, &drLightData);
  285.                 status = Q3DirectionalLight_SetData(light, &drLightData);
  286.             break;
  287.         case kQ3LightTypePoint:
  288.                 VccToPointLightData(vcc, &ptLightData);
  289.                 status = Q3PointLight_SetData(light, &ptLightData);
  290.             break;
  291.         case kQ3LightTypeSpot:
  292.                 VccToSpotLightData(vcc, &spLightData);
  293.                 status = Q3SpotLight_SetData(light, &spLightData);
  294.             break;
  295.     }
  296. }
  297.  
  298.  
  299. // --------------------------------------------------------------------
  300. static void    VccToLightData(VccPtr vcc, TQ3LightData *lightData)
  301. {
  302.     lightData->isOn            = (GetCurrentValue(vcc, 0) == 1.0);
  303.     lightData->brightness    = GetCurrentValue(vcc, 1);
  304.     lightData->color.r        = GetCurrentValue(vcc, 3);
  305.     lightData->color.g        = GetCurrentValue(vcc, 4);
  306.     lightData->color.b        = GetCurrentValue(vcc, 5);
  307. }
  308.  
  309.  
  310. // --------------------------------------------------------------------
  311. static void    VccToDirectLightData(VccPtr vcc, TQ3DirectionalLightData *drLightData)
  312. {
  313.     VccToLightData(vcc, &drLightData->lightData);
  314.  
  315.     drLightData->castsShadows    = (GetCurrentValue(vcc, 7) == 1.0);
  316.     
  317.     drLightData->direction.x    = GetCurrentValue(vcc, 8);
  318.     drLightData->direction.y    = GetCurrentValue(vcc, 9);
  319.     drLightData->direction.z    = GetCurrentValue(vcc, 10);
  320. }
  321.  
  322.  
  323. // --------------------------------------------------------------------
  324. static void    VccToPointLightData (VccPtr vcc, TQ3PointLightData *ptLightData)
  325. {
  326.     VccToLightData(vcc, &ptLightData->lightData);
  327.  
  328.     ptLightData->castsShadows    = (GetCurrentValue(vcc, 7) == 1.0);
  329.     ptLightData->attenuation      = GetCurrentValue(vcc, 8); // 0, 1, 2
  330.     
  331.     ptLightData->location.x        = GetCurrentValue(vcc, 10);
  332.     ptLightData->location.y        = GetCurrentValue(vcc, 11);
  333.     ptLightData->location.z        = GetCurrentValue(vcc, 12);
  334. }
  335.  
  336.  
  337.  
  338. // --------------------------------------------------------------------
  339. static void    VccToSpotLightData (VccPtr vcc, TQ3SpotLightData *spLightData)
  340. {
  341.     VccToLightData(vcc, &spLightData->lightData);
  342.     
  343.     spLightData->castsShadows    = (GetCurrentValue(vcc, 7) == 1.0);
  344.     spLightData->attenuation      = GetCurrentValue(vcc, 8); // 0, 1, 2
  345.     
  346.     spLightData->location.x        = GetCurrentValue(vcc, 10);
  347.     spLightData->location.y        = GetCurrentValue(vcc, 11);
  348.     spLightData->location.z        = GetCurrentValue(vcc, 12);
  349.     
  350.     spLightData->direction.x    = GetCurrentValue(vcc, 14);
  351.     spLightData->direction.y    = GetCurrentValue(vcc, 15);
  352.     spLightData->direction.z    = GetCurrentValue(vcc, 16);
  353.  
  354.     spLightData->hotAngle        = GetCurrentValue(vcc, 18);
  355.     spLightData->outerAngle        = GetCurrentValue(vcc, 19);
  356.     spLightData->fallOff        = GetCurrentValue(vcc, 20); // 0, 1, 2, 3
  357. }
  358.  
  359.  
  360.  
  361.